/**
 * 
 */
package truerefactor.output;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import truerefactor.graph.CodeGraph;

/**
 * @author Isaac
 */
public class OutputDirector {

    /**
     * output builder used to generate the output of the system
     */
    private OutputBuilder builder;
    /**
     * print writer used to write output into files
     */
    private PrintWriter pw;
    /**
     * print writer specifically for the fitness log file
     */
    private PrintWriter fitnessPW;
    /**
     * print writer specifically for the code smell log file
     */
    private PrintWriter smellPW;

    /**
     * Creates a new instance of OutputDirector
     * 
     * @param builder
     *            output builder to be used by this output director
     * @param file
     *            file location to output to
     * @param fitnessLog
     *            fitness log file location
     * @param smellLog
     *            code smell log file location
     */
    public OutputDirector(OutputBuilder builder, File file, File fitnessLog, File smellLog)
    {
        this.builder = builder;

        try
        {
            if (!file.exists())
            {
                file.createNewFile();
            }

            pw = new PrintWriter(file);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try
        {
            if (!fitnessLog.exists())
            {
                fitnessLog.createNewFile();
            }

            fitnessPW = new PrintWriter(fitnessLog);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try
        {
            if (!smellLog.exists())
            {
                smellLog.createNewFile();
            }

            smellPW = new PrintWriter(smellLog);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Starts the process of constructing the output
     * 
     * @param graph
     *            the code graph to derive the output from
     * @param location
     *            location on disk to place the contents of output
     * @param comment
     *            informative comment for the file
     */
    public void constructOutput(CodeGraph graph, String location, String comment)
    {
        builder.setCodeGraph(graph);
        builder.createPackages();
        builder.createClasses();
        builder.createAttributes();
        builder.createMethods();
        builder.createLinksBetweenClasses();
        builder.createOutputFiles(new File(location), comment);
    }

    /**
     * Creates the results report
     * 
     * @param string
     *            string to append into the results report
     */
    public void constructResultsReport(String string)
    {
        pw.append(string);
        pw.flush();
    }

    /**
     * Records fitness information into the fitness log
     * 
     * @param generation
     *            generation to log
     * @param best
     *            best total fitness
     * @param bestVals
     *            component values of the best fitness
     */
    public void recordFitness(int generation, double best, double[] bestVals)
    {
        StringBuilder sb = new StringBuilder();
        sb.append(generation);
        sb.append(",");
        for (int i = 0; i < bestVals.length; i++)
        {
            sb.append(bestVals[i]);
            sb.append(",");
        }
        sb.append(best);
        sb.append("\n");

        fitnessPW.append(sb.toString());
        fitnessPW.flush();
    }

    /**
     * Records a smell line in the code smell log
     * 
     * @param generation
     *            generation to be logged
     * @param smell
     *            best total code smell for the generation
     * @param smells
     *            component values of the code smell to be logged
     */
    public void recordCodeSmell(int generation, double smell, double[] smells)
    {
        StringBuilder sb = new StringBuilder();
        sb.append(generation);
        sb.append(",");
        for (int i = 0; i < smells.length; i++)
        {
            sb.append(smells[i]);
            sb.append(",");
        }
        sb.append(smell);
        sb.append("\n");

        smellPW.append(sb.toString());
        smellPW.flush();
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#finalize()
     */
    @Override
    protected void finalize() throws Throwable
    {
        // TODO Auto-generated method stub
        super.finalize();
        pw.close();
        smellPW.close();
        fitnessPW.close();
    }
}
